#include "log_manager.h"
#include <QDebug>
#include <QCoreApplication>
#include <QStandardPaths>

LogManager* LogManager::instance_ = nullptr;

LogManager* LogManager::getInstance()
{
    if (!instance_) {
        instance_ = new LogManager();
    }
    return instance_;
}

LogManager::LogManager(QObject* parent)
    : QObject(parent)
    , keepDays_(7)
{
}

LogManager::~LogManager()
{
    cleanup();
}

void LogManager::init(const QString& logDir, int keepDays)
{
    QMutexLocker locker(&mutex_);
    
    logDir_ = logDir;
    keepDays_ = keepDays;
    
    QDir dir(logDir_);
    if (!dir.exists()) {
        dir.mkpath(".");
    }
    
    // 清理旧日志文件
    cleanOldLogs();
    
    // 安装消息处理器
    qInstallMessageHandler(messageHandler);
    
    // 打开日志文件
    openLogFile();
}

void LogManager::cleanup()
{
    QMutexLocker locker(&mutex_);
    closeLogFile();
    qInstallMessageHandler(nullptr);
}

void LogManager::openLogFile()
{
    currentDate_ = QDateTime::currentDateTime().toString("yyyy-MM-dd");
    QString logFilePath = QString("%1/log_%2.txt").arg(logDir_).arg(currentDate_);
    
    logFile_.setFileName(logFilePath);
    if (!logFile_.open(QIODevice::WriteOnly | QIODevice::Append | QIODevice::Text)) {
        qWarning() << "Failed to open log file:" << logFilePath;
        return;
    }
    
    logStream_.setDevice(&logFile_);
    logStream_.setCodec("UTF-8");
}

void LogManager::closeLogFile()
{
    if (logFile_.isOpen()) {
        logStream_.flush();
        logFile_.close();
    }
}

void LogManager::checkAndRotateLogFile()
{
    QString today = QDateTime::currentDateTime().toString("yyyy-MM-dd");
    if (today != currentDate_) {
        closeLogFile();
        openLogFile();
        cleanOldLogs(); // 每天切换日志文件时清理旧文件
    }
}

void LogManager::cleanOldLogs()
{
    QDir dir(logDir_);
    if (!dir.exists()) {
        return;
    }
    
    // 获取当前日期
    QDate currentDate = QDate::currentDate();
    
    // 获取所有日志文件
    QStringList filters;
    filters << "log_*.txt";
    dir.setNameFilters(filters);
    dir.setFilter(QDir::Files);
    
    QFileInfoList fileList = dir.entryInfoList();
    for (const QFileInfo& fileInfo : fileList) {
        // 从文件名中提取日期
        QString fileName = fileInfo.fileName();
        QString dateStr = fileName.mid(4, 10); // 提取"log_YYYY-MM-DD.txt"中的日期部分
        
        QDate fileDate = QDate::fromString(dateStr, "yyyy-MM-dd");
        if (fileDate.isValid()) {
            // 计算文件日期与当前日期的天数差
            int daysDiff = fileDate.daysTo(currentDate);
            if (daysDiff > keepDays_) {
                // 删除超过保留天数的文件
                QFile::remove(fileInfo.absoluteFilePath());
            }
        }
    }
}

void LogManager::messageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    QMutexLocker locker(&instance_->mutex_);
    
    // 检查是否需要切换日志文件
    instance_->checkAndRotateLogFile();
    
    // 获取当前时间
    QString timestamp = QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
    
    // 获取类名和函数名
    QString className = QString(context.category).isEmpty() ? "Unknown" : context.category;
    QString functionName = QString(context.function).isEmpty() ? "Unknown" : context.function;
    
    // 格式化日志消息
    QString logMessage;
    switch (type) {
        case QtDebugMsg:
            logMessage = QString("[%1] [DEBUG] [%2::%3] %4").arg(timestamp).arg(className).arg(functionName).arg(msg);
            break;
        case QtInfoMsg:
            logMessage = QString("[%1] [INFO] [%2::%3] %4").arg(timestamp).arg(className).arg(functionName).arg(msg);
            break;
        case QtWarningMsg:
            logMessage = QString("[%1] [WARNING] [%2::%3] %4").arg(timestamp).arg(className).arg(functionName).arg(msg);
            break;
        case QtCriticalMsg:
            logMessage = QString("[%1] [CRITICAL] [%2::%3] %4").arg(timestamp).arg(className).arg(functionName).arg(msg);
            break;
        case QtFatalMsg:
            logMessage = QString("[%1] [FATAL] [%2::%3] %4").arg(timestamp).arg(className).arg(functionName).arg(msg);
            break;
    }
    
    // 写入日志文件
    if (instance_->logFile_.isOpen()) {
        instance_->logStream_ << logMessage << "\n";
        instance_->logStream_.flush();
    }
    
    // 同时输出到控制台
    QByteArray localMsg = logMessage.toLocal8Bit();
    fprintf(stderr, "%s\n", localMsg.constData());
    fflush(stderr);
} 